package org.brownflat.watergate.domain;

import org.brownflat.watergate.job.TriggerReviewsJob;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;

import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>&copy Rupert Jones 2012</p>
 *
 * @author rup
 */
@Entity
@Table(name = "wgate_branch")
public class Branch extends BaseEntity {

    @OneToMany(mappedBy="branch", orphanRemoval = true)
    @Access(value= AccessType.PROPERTY)
    @Cascade( { org.hibernate.annotations.CascadeType.ALL } )
    @OrderBy("revision desc")
    private List<Commit> commits = new ArrayList<Commit>();

    @LazyCollection(LazyCollectionOption.FALSE)
    @OneToMany(mappedBy="branch", orphanRemoval = true)
    @Access(value= AccessType.PROPERTY)
    @Cascade( { org.hibernate.annotations.CascadeType.ALL } )
    private List<ReviewTrigger> reviewTriggers = new ArrayList<ReviewTrigger>();

    @ManyToOne
    @JoinColumn(name="repository")
    private Repository repository;

    @Column
    private String name;

    @Column
    private String path;

    @ManyToOne
    @JoinColumn(name="def_review_group")
    private Group defaultReviewingGroup;

    @Column(name="start_revision")
    private long startRevision = 0;

    public List<Commit> getCommits() {
        return commits;
    }

    public void setCommits(List<Commit> commits) {
        this.commits = commits;
    }

    public Repository getRepository() {
        return repository;
    }

    public void setRepository(Repository repository) {
        this.repository = repository;
    }

    public Group getDefaultReviewingGroup() {
        return defaultReviewingGroup;
    }

    public void setDefaultReviewingGroup(Group defaultReviewingGroup) {
        this.defaultReviewingGroup = defaultReviewingGroup;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    public void addCommit(Commit commit) {
        this.commits.add(commit);
    }

    public String getFullPath() {
        return String.format("%s/%s", repository.getUrl(), path);
    }

    public List<ReviewTrigger> getReviewTriggers() {
        return reviewTriggers;
    }

    public void setReviewTriggers(List<ReviewTrigger> reviewTriggers) {
        this.reviewTriggers = reviewTriggers;
    }

    public void addReviewTrigger(ReviewTrigger reviewTrigger) {
        this.reviewTriggers.add(reviewTrigger);
    }

    public Commit getLastCommit() {
        if(commits != null && commits.size() > 0) {
            return commits.get(0);
        }
        return null;
    }

    public String getUniqueBranchKey() {
        return String.format("branchId:%s-branchName:%s", getId(), getName());
    }

    public long getStartRevision() {
        return startRevision;
    }

    public void setStartRevision(long startRevision) {
        this.startRevision = startRevision;
    }

    public boolean shouldTriggerReviewWith(Commit commit) {
        for(ReviewTrigger reviewTrigger: reviewTriggers) {
            if(reviewTrigger.match(commit)) {
                return true;
            }
        }
        return false;
    }
}
